home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 422_04 / cc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-20  |  5.9 KB  |  216 lines

  1. /*
  2.  * DDS MICRO-C Command Coordinator
  3.  *
  4.  * This program integrates the various commands required to compile a
  5.  * program into a single command. It is currently set up for the PC/8086
  6.  * compiler (using MASM and LINK).
  7.  *
  8.  * The following command switches are used with MASM and LINK:
  9.  *
  10.  *  MASM: /t = Terse (no messages)  /ml = Upper/Lower case sensitive
  11.  *    LINK: /noi = Do not ignore case (Upper/Lower case sensitive)
  12.  *
  13.  * If your version(s) of MASM/LINK (or compatible) does not work with
  14.  * the command lines hard coded in this program, do the following:
  15.  *
  16.  * - Modify CC.C and LC.BAT (if necessary) to use acceptable commands
  17.  * - Compile CC.C to CC.ASM using: CC CC -afo
  18.  * - Assemble with your assembler
  19.  * - Link to a new CC.COM with: LC CC
  20.  *
  21.  * If either your assembler OR linker does not support case sensitive
  22.  * operation, run BOTH of them in case insensitive mode, and be sure
  23.  * not to use any global symbols which differ only in case.
  24.  *
  25.  * Copyright 1990-1994 Dave Dunfield
  26.  * All rights reserved.
  27.  *
  28.  * Compile command: cc cc -fop
  29.  */
  30. #include <stdio.h>
  31.  
  32. #define    NOFILE    2        /* EXEC return code for file not found */
  33. #define    NOPATH    3        /* EXEC return code for path not found */
  34.  
  35. char mcdir[65], temp[65], ofile[65], tail[150], mcparm[80];
  36. char oasm = -1, opt = 0, pre = 0, tiny = -1, link = -1, verb = -1,
  37.     del = -1, com = 0, fold = 0, *fnptr, *mptr = &mcparm;
  38.  
  39. /*
  40.  * Main program, process options & invoke appropriate commands
  41.  */
  42. main(argc, argv)
  43.     int argc;
  44.     char *argv[];
  45. {
  46.     int i;
  47.     char ifile[65], *ptr, c;
  48.  
  49.     /* Get default directories from environment */
  50.     if(!getenv("MCDIR", mcdir))        /* Get MICRO-C directory */
  51.         strcpy(mcdir,"\\MC");
  52.     if(!getenv("MCTMP", temp))        /* Get temporary directory */
  53.         strcpy(temp,"$");
  54.  
  55. /* parse for command line options. */
  56.     for(i=2; i < argc; ++i) {
  57.         if(*(ptr = argv[i]) == '-') {        /* Enable switch */
  58.             while(*++ptr) {
  59.                 switch(toupper(*ptr)) {
  60.                     case 'A' : oasm = 0;    continue;
  61.                     case 'C' : com = -1;    continue;
  62.                     case 'F' : fold = -1;    continue;
  63.                     case 'K' : del = 0;        continue;
  64.                     case 'L' : link = 0;    continue;
  65.                     case 'O' : opt = -1;    continue;
  66.                     case 'P' : pre = -1;    continue;
  67.                     case 'Q' : verb = 0;    continue;
  68.                     case 'S' : tiny = 0;    continue; }
  69.                 goto badopt; }
  70.             continue; }
  71.  
  72.         if(*(ptr+1) == '=') switch(toupper(*ptr)) {
  73.             case 'H' : strcpy(mcdir, ptr+2);    continue;
  74.             case 'T' : strcpy(temp, ptr+2);        continue; }
  75.  
  76.         *mptr++ = ' ';
  77.         c = 0;
  78.         while(*mptr++ = *ptr++) {
  79.             if(*ptr == '=')
  80.                 c = pre; }
  81.         if(c)
  82.             continue;
  83.  
  84.     badopt:
  85.         fprintf(stderr,"Invalid option: %s\n", argv[i]);
  86.         exit(-1); }
  87.  
  88.     message("DDS MICRO-C 8086 Compiler v3.02\n");
  89.  
  90.     if(argc < 2)
  91.         abort("\nUse: CC <name> [-acfklopqs h=homedir t=tmpdir] [symbol=value]\n\nCopyright 1990-1994 Dave Dunfield\nAll rights reserved.\n");
  92.  
  93.     /* Parse filename & extension from passed path etc. */
  94.     fnptr = ptr = argv[1];
  95.     while(c = *ptr) {
  96.         if(c == '.')
  97.             goto noext;
  98.         ++ptr;
  99.         if((c == ':') || (c == '\\'))
  100.             fnptr = ptr; }
  101.     strcpy(ptr, ".C");
  102. noext:
  103.     strcpy(ifile, argv[1]);
  104.     message(fnptr);
  105.     message(": ");
  106.     *mptr = *ptr = 0;
  107.  
  108.     /* Pre-process to source file */
  109.     if(pre) {
  110.         message("Preprocess... ");
  111.         sprintf(ofile,"%s%s.CP", temp, fnptr);
  112.         sprintf(tail,"%s %s l=%s -q -l%s", ifile, ofile, mcdir, mcparm);
  113.         docmd("MCP");
  114.         strcpy(ifile, ofile); }
  115.  
  116.     /* Compile to assembly language */
  117.     message("Compile... ");
  118.     sprintf(ofile,"%s%s.%s", (oasm||opt) ? temp : "", fnptr,
  119.         opt ? "CO" : "ASM");
  120.     sprintf(tail,"%s %s -q%s%s%s", ifile, ofile, pre ? " -l" : "",
  121.         com ? " -c" : "", fold ? " -f" : "");
  122.     docmd("MCC");
  123.     if(pre)
  124.         erase(ifile);
  125.     strcpy(ifile, ofile);
  126.  
  127.     /* Optimize the assembly language */
  128.     if(opt) {
  129.         message("Optimize... ");
  130.         sprintf(ofile,"%s%s.ASM", oasm ? temp : "", fnptr);
  131.         sprintf(tail, "%s %s -q", ifile, ofile);
  132.         docmd("MCO");
  133.         erase(ifile);
  134.         strcpy(ifile, ofile); }
  135.  
  136.     /* Assemble into object module */
  137.     if(oasm) {
  138.         message("Assemble... ");
  139.         sprintf(ofile,"%s%s.OBJ", link ? temp : "", fnptr);
  140.         sprintf(tail,"/t/ml %s,%s;", ifile, ofile);
  141.         docmd("MASM");
  142.         erase(ifile);
  143.         strcpy(ifile, ofile);
  144.  
  145.     /* Link into executable program */
  146.         if(link) {
  147.             sprintf(ofile,"%s.EXE", fnptr);
  148.             message(tiny ? "Link TINY...\n" : "Link SMALL...\n");
  149.             sprintf(tail,"/NOI %s\\PC86RL_%c %s,%s,NUL,%s\\MCLIB;",
  150.                 mcdir, tiny ? 'T' : 'S', ifile, ofile, mcdir);
  151.             docmd("LINK");
  152.             erase(ifile);
  153.             if(tiny) {
  154.                 strcpy(ifile, ofile);
  155.                 message("Convert... ");
  156.                 sprintf(tail,"%s %s.COM", ofile, fnptr);
  157.                 docmd("EXE2BIN");
  158.                 erase(ofile); } } }
  159.  
  160.     message("All done.\n");
  161. }
  162.  
  163. /*
  164.  * Execute a command, looking for it in the MICRO-C directory,
  165.  * and also in any directories found in the PATH environment
  166.  * variable. Operands to the command have been previously
  167.  * defined in the global variable 'tail'.
  168.  */
  169. docmd(cmd)
  170.     char *cmd;
  171. {
  172.     int rc;
  173.     char command[65], path[300], *ptr, *ptr1, *delim, c;
  174.  
  175.     ptr = mcdir;                        /* First try MC home dir */
  176.     if(!getenv("PATH", ptr1 = path))    /* And then search  PATH */
  177.         ptr1 = "";
  178.  
  179.     do {    /* Search MCDIR & PATH for commands */
  180.         delim = "\\"+(ptr[strlen(ptr)-1] == '\\');
  181.         sprintf(command,"%s%s%s.COM", ptr, delim, cmd);
  182.         if((rc = exec(command, tail)) == NOFILE) {
  183.             sprintf(command,"%s%s%s.EXE", ptr, delim, cmd);
  184.             rc = exec(command, tail); }
  185.         ptr = ptr1;                        /* Point to next directory */
  186.         while(c = *ptr1) {                /* Advance to end of entry */
  187.             ++ptr1;
  188.             if(c == ';') {
  189.                 *(ptr1 - 1) = 0;        /* Zero terminate */
  190.                 break; } } }
  191.     while(((rc == NOFILE) || (rc == NOPATH)) && *ptr);
  192.     if(rc) {
  193.         fprintf(stderr,"%s failed (%d)\n", cmd, rc);
  194.         exit(-1); }
  195. }
  196.  
  197. /*
  198.  * Output an informational message (verbose mode only)
  199.  */
  200. message(ptr)
  201.     char *ptr;
  202. {
  203.     if(verb)
  204.         fputs(ptr, stderr);
  205. }
  206.  
  207. /*
  208.  * Erase temporary file (if enabled)
  209.  */
  210. erase(file)
  211.     char *file;
  212. {
  213.     if(del)
  214.         delete(file);
  215. }
  216.